# -*- coding: utf-8 -*-
# @FileName : PayService.py
# @Time     : 2023/6/11 19:02
# @Author   : Zhong Runke
import decimal
import hashlib
import json
import random
import time

from application import app, db
from common.libs.webase.WebaseService import WebaseService
from common.models.Goods import Goods
from common.models.Order import Order
from common.libs.Helper import getCurrentDate
from common.models.OrderItem import OrderItem
from common.models.Wallet import Wallet


class PayService():

    def __init__(self):
        pass

    def createOrder(self, userAddress, items=None, params=None):
        """
        :param userAddress:
        :param items: [{'id': 15, 'price': '20.00', 'number': 1}]
        :param params:
        :return: {'code': 200, 'msg': 'OK', 'data': {}}
        """
        resp = {'code': 200, 'msg': 'OK', 'data': {}}
        pay_price = decimal.Decimal(0.00)
        continue_cnt = 0
        good_ids = []
        for item in items:
            if decimal.Decimal(item['price']) < 0:
                continue_cnt += 1
                continue

            pay_price = pay_price + decimal.Decimal(item['price']) * int(item['number'])
            good_ids.append(item['id'])

        if continue_cnt >= len(items):
            resp['code'] = -1
            resp['msg'] = '商品items为空'
            return resp

        yun_price = params['yun_price'] if params and 'yun_price' in params else 0
        note = params['note'] if params and 'note' in params else ''
        express_address_id = params['express_address_id'] if params and 'express_address_id' in params else 0
        express_info = params['express_info'] if params and 'express_info' in params else {}
        yun_price = decimal.Decimal(yun_price)
        total_price = pay_price + yun_price

        wallet_info = Wallet.query.filter_by(useraddress=userAddress).first()
        if wallet_info.balance < total_price:
            resp['code'] = -1
            resp['msg'] = '钱包余额不足'
            return resp
        try:
            #
            tmp_good_list = db.session.query(Goods).filter(Goods.id.in_(good_ids)) \
                .with_for_update().all()
            print("=============tmp_good_list================")
            print(tmp_good_list)
            print(items)
            good_info = tmp_good_list[0]
            # tmp_good_stock_mapping = {}
            # for tmp_item in tmp_good_list:
            #     tmp_good_stock_mapping[tmp_item.id] = tmp_item.stock
            # 链上创建订单
            # 修改钱包信息
            order_sn = self.geneOrderSn()
            webase_resp = WebaseService.commonReq(userAddress, "createOrder",
                                                  [good_info.itemIdCounter],
                                                  app.config['WEBASE_CONTRACTABI'],
                                                  app.config['WEBASE_CONTRACTNAME'],
                                                  app.config['WEBASE_CONTRACTADDRESS'])
            webase_dict = json.loads(webase_resp)
            if webase_dict['message'] != 'Success':
                resp['code'] = -1
                resp['msg'] = '区块链异常'
                return resp
            print("=================webase====================")
            print(webase_dict)
            orderIdCounterStr = webase_dict['output']
            orderIdCounter = int(orderIdCounterStr, 16)
            model_order = Order()
            model_order.order_sn = order_sn
            model_order.seller = good_info.useraddress
            model_order.buyer = userAddress
            model_order.goodsNumber = good_info.id
            model_order.price = total_price
            model_order.note = note
            model_order.status = -8
            model_order.express_status = -8
            model_order.express_address_id = express_address_id
            model_order.express_info = json.dumps(express_info)
            model_order.orderIdCounter = orderIdCounter
            model_order.blocknum = webase_dict['blockNumber']
            model_order.blockHash = webase_dict['blockHash']
            model_order.transactionhash = webase_dict['transactionHash']
            model_order.updated_time = model_order.created_time = getCurrentDate()
            db.session.add(model_order)
            db.session.flush()
            for item in items:
                tmp_pay_item = OrderItem()
                tmp_pay_item.order_id = model_order.id
                tmp_pay_item.userAddress = model_order.buyer
                tmp_pay_item.quantity = item['number']
                tmp_pay_item.price = item['price']
                tmp_pay_item.good_id = item['id']
                tmp_pay_item.note = note
                tmp_pay_item.status = 1
                tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentDate()
                db.session.add(tmp_pay_item)
            db.session.commit()

            # 将该商品修改商品状态
            good_info.status = 2  # 下架
            db.session.add(good_info)
            db.session.commit()

            resp['data'] = {
                'id' : model_order.id,
                'order_sn' : model_order.order_sn,
                'total_price':str(total_price)
            }
        except Exception as e:
            db.session.rollback()
            print( e )
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)
            return resp

        return resp

    def geneOrderSn(self):
        m = hashlib.md5()
        sn = None
        while True:
            str = '%s-%s' % (int(round(time.time() * 1000)), random.randint(0, 9999999))
            m.update(str.encode("utf-8"))
            sn = m.hexdigest()

            if not Order.query.filter_by(order_sn=sn).first():
                break
        return sn

    def closeOrder(self, order_id=0):
        if order_id < 1:
            return False
        order_info = Order.query.filter_by(id=order_id, status=-8).first()
        if not order_info:
            return False

        try:
            order_items = OrderItem.query.filter_by(order_id=order_id).all()
            if order_items:
                for item in order_items:
                    item.status = 0
                    item.updated_time = getCurrentDate()
                    item.note = "订单取消"
                    good_info = Goods.query.filter_by(id=item.good_id, status=2).first()
                    if good_info:
                        good_info.status = 1
                        good_info.updated_time = getCurrentDate()
                        db.session.add(good_info)
                    db.session.add(item)

            order_info.status = 0
            order_info.updated_time = getCurrentDate()

            db.session.add(order_info)
            db.session.commit()
        except:
            db.session.rollback()
            return False

        return True
